package com.yerbamateprimer.round.state;

import java.util.List;

import com.yerbamateprimer.action.system.SystemAction;
import com.yerbamateprimer.action.user.UserAction;
import com.yerbamateprimer.round.Round;
import com.yerbamateprimer.round.state.exit.StateExit;
import com.yerbamateprimer.round.state.exit.StateExitCause;

/**
 * This interface defines 
 * a state of yerba mate 
 * round.
 * 
 * @author Matias Liwski
 * @version 1.0
 */
public interface State {
	/**
	 * @param stateName The name of this state, to set.
	 */
	void setName(StateName stateName);

	/**
	 * @return The name of this state.
	 */
	StateName getName();

	/**
	 * @return The status of this state.
	 */
	StateStatus getStatus();

	/**
	 * @param action A system action to add.
	 */
	void addGetInAction(SystemAction action);

	/**
	 * @return The list of actions to execute when get in the state. 
	 */
	List<SystemAction> getGetInActions();

	/**
	 * @param delay The delay before auto get out of state, to set.
	 */
	void setAutoGetOutDelay(Long delay);

	/**
	 * @return The delay before auto get out of state.
	 */
	Long getAutoGetOutDelay();

	/**
	 * @param exit An exit to this state, to add.
	 */
	void addExit(StateExit exit);

	/**
	 * @return All the possible exits of this state.
	 */
	List<StateExit> getExits();

	/**
	 * @param exitCause The state exit cause.
	 * @return The StateExit for the provided exit cause.
	 */
	StateExit getExit(StateExitCause exitCause);

	/**
	 * Get into this state.
	 * 
	 * @param round The round where the state belongs (It's send in the method to avoid cycle "knowledge" of each other).
	 */
	void getIn(Round round);

	/**
	 * Force the get out of this state.
	 * 
	 * @param round The round where the state belongs (It's send in the method to avoid cycle "knowledge" of each other).
	 */
	void getOut(Round round);

	/**
	 * Executes an action in the current state.
	 * 
	 * @param action The action to execute.
	 */
	void execute(UserAction action);
}